package fr.noe.amicaleloisirs.concours.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;

import org.apache.log4j.Logger;

public class FileUtil {

	private static Logger logger = Logger.getLogger(FileUtil.class);

	private static void log(String text) {
		logger.debug(text);
	}

	private static File getFile(String src) {
		return new File(src);
	}

	public static boolean fileDelete(final String file) {
		// --- hosted mode implementation
		File f = getFile(file);
		if (!f.exists())
			return true;
		return f.delete();
	}

	public static boolean dirCreate(final String dirname) {
		// --- hosted mode implementation
		File d = getFile(dirname);
		if (d.exists()) {
			if (d.isFile()) {
				return false;
			}
			return true;
		}
		return d.mkdirs();
	}

	public static boolean dirDelete(final String dirname) {
		// --- hosted mode implementation
		File d = getFile(dirname);
		if (!d.exists()) {
			return true;
		}
		if (d.isFile()) {
			return false;
		}

		return deleteDirectory(d);
	}

	private static boolean deleteDirectory(File path) {
		if (path.exists()) {
			File[] files = path.listFiles();
			if (files != null) {
				for (int i = 0; i < files.length; i++) {
					if (files[i].isDirectory()) {
						deleteDirectory(files[i]);
					} else {
						files[i].delete();
					}
				}
			}
		}
		return (path.delete());
	}

	public static boolean dirExists(final String dirname) {
		File d = getFile(dirname);
		return d.exists() && d.isDirectory();
	}

	public static boolean fileExists(final String filename) {
		File d = getFile(filename);
		return d.exists() && d.isFile();
	}

	public static boolean copy(final String srcfilename,
			final String dstfilename) {
		// --- hosted mode implementation
		File src = getFile(srcfilename);
		if (!src.exists()) {
			return false;
		}
		if (!src.isFile()) {
			return false;
		}
		File dest = getFile(dstfilename);
		if (dest.exists()) {
			return false;
		}
		// --- ensure dest path exists
		dest.getParentFile().mkdirs();
		try {
			InputStream in = new FileInputStream(src);
			OutputStream out = new FileOutputStream(dest);
			byte[] buf = new byte[1024];
			int len;
			while ((len = in.read(buf)) > 0)
				out.write(buf, 0, len);
			out.flush();
			out.close();
			in.close();
			return true;
		} catch (IOException e) {
			log(e.getMessage());
			return false;
		}
	}

	public static boolean move(final String srcfilename,
			final String dstfilename) {
		File src = getFile(srcfilename);
		if (!src.exists()) {
			return false;
		}
		if (!src.isFile()) {
			return false;
		}
		File dest = getFile(dstfilename);
		if (dest.exists()) {
			return false;
		}
		// --- ensure dest path exists
		dest.getParentFile().mkdirs();
		return src.renameTo(dest);
	}

	public static String read(final String filename) {
		log("Read called with filename: " + filename);
		try {
			String content = _read(filename);
			return content;
		} catch (FileNotFoundException e) {
			log(e.getMessage());
			return null;
		} catch (IOException e) {
			log(e.getMessage());
			return null;
		}
	}

	private static String _read(final String filename) throws IOException, FileNotFoundException {
		File f = getFile(filename);
		if (!f.exists())
			throw new FileNotFoundException("file '" + filename + "' not found");
		if (!f.isFile())
			throw new IOException("'" + filename + "' not a file");
		FileReader in = new FileReader(f);
		StringBuffer text = new StringBuffer();
		char[] buf = new char[1024];
		int len;
		while ((len = in.read(buf)) > 0)
			text.append(buf, 0, len);
		in.close();
		return text.toString();
	}

	public static boolean write(final String filename, final String content) {
		log("write content into file: " + filename);
		try {
			_write(filename, content, false);
			log("write done.");
			return true;
		} catch (IOException e) {
			log(e.getMessage());
			return false;
		}
	}

	public static boolean append(final String filename, final String content) {
		log("append content into file: " + filename);
		try {
			_write(filename, content, true);
			return true;
		} catch (IOException e) {
			log(e.getMessage());
			return false;
		}
	}

	private static void _write(final String filename, final String content,
			final boolean append) throws IOException {
		// --- hosted mode implementation
		File f = getFile(filename);
		// --- ensure dest path exists
		f.getParentFile().mkdirs();

		FileWriter out = new FileWriter(f, append);
		out.write(content);
		out.flush();
		out.close();
	}

	public static String[] dirList(final String dirname) {
		// --- hosted mode implementation
		File dir = getFile(dirname);
		if (!dir.exists()) {
			return null;
		}
		if (!dir.isDirectory()) {
			return null;
		}
		File[] files = dir.listFiles();
		if (files == null || files.length == 0)
			return null;
		ArrayList<String> stringFiles = new ArrayList<String>();
		for (File f : files) {
			stringFiles.add(f.getName());
		}
		return (String[]) stringFiles.toArray();

	}
}
